<?php

namespace Cblood\Sword\Operation;


abstract class OrganizeSqlBasic
{
    protected $table = null;

    public function table($table)
    {
        $this->table = $table;
        return $this;
    }

    /**
     * 供子类使用
     * @return mixed
     * @throws \Exception
     */
    protected function getTable()
    {
        if (empty($this->table)) {
            throw new \Exception('sql语句错误，无table');
        }
        return $this->table;
    }


    /**
     * @param array|string $filed
     * @return string
     */
    protected function finishingField($filed)
    {
        return is_array($filed) ? implode(',', $filed) : $filed;
    }

    /**
     *    $where = array(
     *      0 => array(
     *      'conjunctions' => $conjunctions,
     *      'sql' => $sql
     *      )
     *      .......
     *    );
     * @var
     */
    protected $where = array();

    protected $field = '*';

    protected $limit = null;

    protected $orderBy = null;


    /**
     * 生成 where 的sql语句
     * @return string
     */
    public function createWhereConditions()
    {
        $sql = '';
        for ($i = 0; $i < count($this->where); $i++) {
            if (!empty($sql)) {
                $sql .= ' ' . $this->where[$i]['conjunctions'] . ' ';
            }

            $sql .= $this->where[$i]['sql'];
        }
        return $sql;
    }

    /**
     * 以数组的形式
     * 添加 sql 的 where 条件
     * 例如 where(['name' => 'value'])                对应sql：where name='value'
     * 例如 where(['name' => '%value%'] , 'like')     对应sql：where name like '%value%'
     * 例如 where(['name' => 'value' , 'name2' => 'value2'] , '!=' , 'OR')
     * 对应sql：where name != 'value' or name2 != 'value2'
     *
     * 执行多个 where()，那么每一个 where 生成的sql语句相对独立
     * 例如 $organizeWhere->where(['name' => 'value'])->where(['name2' => 'value2'])
     * 对应sql：where (name='value') AND (name2='value2')
     * @param array $conditions
     * @param string $conjunctions
     * @param string $withinConjunctions
     * @return $this
     */
    public function where(array $conditions, $withinConjunctions = 'AND', $conjunctions = '=')
    {
        $whereSql = $this->organizeWhere($conditions, $withinConjunctions, $conjunctions);
        $this->where[] = array(
            'sql' => $whereSql,
            'conjunctions' => 'AND'
        );
        return $this;
    }

    /**
     * 同 where 方法
     * 区别在于每一个独立 sql 连接词不同，这个是 OR
     * @param array $conditions
     * @param string $conjunctions
     * @param string $withinConjunctions
     * @return $this
     */
    public function orWhere(array $conditions, $withinConjunctions = 'AND', string $conjunctions = '=')
    {
        $whereSql = $this->organizeWhere($conditions, $withinConjunctions, $conjunctions);
        $this->where[] = array(
            'sql' => $whereSql,
            'conjunctions' => 'OR'
        );
        return $this;
    }

    /**
     * 设置查询字段
     * @param $selectField
     * @return $this
     */
    public function field($selectField)
    {
        $this->field = $this->finishingField($selectField);
        return $this;
    }

    /**
     * 添加 order by
     * @param array|string $field
     * @param string $sorting 默认升序
     * @return $this
     */
    public function orderBy($field, $sorting = 'ASC')
    {
        $orderBySql = $this->finishingField($field);
        $this->orderBy = ' ORDER BY ' . $orderBySql . ' ' . $sorting;
        return $this;
    }

    /**
     * 添加 limit
     * @param string $limit
     * @return $this
     */
    public function limit($limit)
    {
        $this->limit = ' LIMIT ' . $limit;
        return $this;
    }

    public function clean()
    {
        $this->limit = null;
        $this->orderBy = null;
        $this->where = array();
        $this->field = '*';
        $this->table = null;
    }

    /**
     * 组织 where 的 sql 语句
     * @param array $conditions
     * @param string $conjunctions
     * @param string $withinConjunctions
     * @return string
     * @throws \Exception
     */
    protected function organizeWhere(array $conditions, $withinConjunctions = 'AND', $conjunctions = '=')
    {
        $sqlArray = array();
        foreach ($conditions as $name => $value) {
            if (is_array($value)) {
                for ($i = 0; $i < count($value); $i++) {
                    $sqlArray[] = ' ' . $name . ' ' . $conjunctions . ' ' . '\'' . $value[$i] . '\' ';
                }
            } else {
                $sqlArray[] = ' ' . $name . ' ' . $conjunctions . ' ' . '\'' . $value . '\' ';
            }
        }

        return '(' . implode($withinConjunctions, $sqlArray) . ')';
    }
}